// Fill out your copyright notice in the Description page of Project Settings.


#include "OSSTaskLib.h"
#include "AliyunOssTask.h"

bool isLink = false;
/*
* 创建一个oss客户端连接,只需要再启动程序时调用一次 一般在UGameInstance的init中调用
* 不支持链接多个Bucket
* @ param outMessage	返回的提示信息
*/
bool UOSSTaskLib::ConstructionOssLink(
	FString accessKeyId, FString accessKeySecret, FString endpoint, FString& outMessage) 
{
	if (isLink) 
	{
		outMessage = TEXT("链接已经建立,不要重复创建!");
		return false;
	}

	FOssOssClientInfo linkInfo = FOssOssClientInfo(accessKeyId, accessKeySecret, endpoint);

	if (accessKeyId.Len() <= 8) {
		outMessage = TEXT("accessKeyId 太短");
		return false;
	}

	if (accessKeySecret.Len() <= 16) {
		outMessage = TEXT("accessKeySecret 太短");
		return false;
	}

	if (endpoint.Len() <= 16) {
		outMessage = TEXT("endpoint 太短");
		return false;
	}

	if (FOssClient::LinkClient(linkInfo))
	{
		isLink = true;
		outMessage = TEXT("创建成功");
		return true;
	}
	outMessage = TEXT("创建失败,请检查输入参数");
	return false;
}

/*
* 开始一个同步任务
* @ param url			下载的url
* @ param savePath		文件保存路径
* @ param errorMessge	返回的错误休息
*/
bool UOSSTaskLib::StartBlockDown(FString url, FString savePath, FString& errorMessge) 
{
	FAliyunOssTaskInfo info = FAliyunOssTaskInfo(EAliyunOssType::DownloadByObject, url, savePath);
	return FAliyunOssTask::DoSynchronizationTask(info, &errorMessge);
}


struct FSTUserKey 
{
	int key = 0;
//#pragma optimize("",off)
	FSTUserKey(const int& k) :key(k) 
	{
		//GLog->Log(FString::Printf(TEXT("make== %i"), key));
	}

	//~FSTUserKey()
	//{		
	//	//GLog->Log(FString::Printf(TEXT("~delete == %i"), key));		
	//}
//#pragma optimize("",on)
};

/*
* 开始一个异步任务
* @ param url			下载的url
* @ param savePath		文件保存路径
* @ param userKey		用户可以指定一个唯一id ,下载过程和完成的回调中会返回给用户
* 方便用户判断任务情况
* @ param onProgress	任务进度回调
* @ param onComplete	完成后的回调
*/
bool UOSSTaskLib::StartAsynchronousDown(
	FString url, FString savePath, int userKey
	, FOssProgressCallBack onProgress, FOssCompleteCallBack onComplete) 
{
	FAliyunOssTaskInfo info = FAliyunOssTaskInfo(EAliyunOssType::DownloadByObject, url, savePath);

	FOssCallBackFunction callBackFunction;

	callBackFunction.onProgress.BindLambda([onProgress](float fPercent, void* OutUserData)
		{			
			int key = ((FSTUserKey*)OutUserData)->key;
			//GLog->Log(FString::Printf(TEXT("onProgress %i << %0.3f"), key, fPercent));
			onProgress.ExecuteIfBound(key,fPercent);
		}
	);

	callBackFunction.onCompleteWithMsg.BindLambda([onComplete](float fPercent, void* OutUserData, FString message)
		{
			int key = ((FSTUserKey*)OutUserData)->key;
			onComplete.ExecuteIfBound(key, message);
			GLog->Log(FString::Printf(TEXT("  onComplete %i <<task"), key));
			//释放内存
			delete ((FSTUserKey*)OutUserData);
		}
	);

	//GLog->Log(FString::Printf(TEXT("userKey== %i==========="), userKey));

	//在完成的回调中释放
	FSTUserKey* key = new FSTUserKey(userKey);
	FAutoDeleteAsyncTask<FAliyunOssTask>* DownloadTask = new FAutoDeleteAsyncTask<FAliyunOssTask>(info, callBackFunction, key);
	DownloadTask->StartBackgroundTask();

	return true;
}

